package com.solcoo.common.network;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Map.Entry;

import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import ch.boye.httpclientandroidlib.HttpResponse;
import ch.boye.httpclientandroidlib.HttpVersion;
import ch.boye.httpclientandroidlib.client.HttpClient;
import ch.boye.httpclientandroidlib.client.methods.HttpGet;
import ch.boye.httpclientandroidlib.client.methods.HttpPost;
import ch.boye.httpclientandroidlib.conn.ConnectTimeoutException;
import ch.boye.httpclientandroidlib.conn.scheme.PlainSocketFactory;
import ch.boye.httpclientandroidlib.conn.scheme.Scheme;
import ch.boye.httpclientandroidlib.conn.scheme.SchemeRegistry;
import ch.boye.httpclientandroidlib.conn.ssl.SSLSocketFactory;
import ch.boye.httpclientandroidlib.entity.mime.HttpMultipartMode;
import ch.boye.httpclientandroidlib.entity.mime.MultipartEntity;
import ch.boye.httpclientandroidlib.entity.mime.content.FileBody;
import ch.boye.httpclientandroidlib.entity.mime.content.StringBody;
import ch.boye.httpclientandroidlib.impl.client.DefaultHttpClient;
import ch.boye.httpclientandroidlib.impl.conn.PoolingClientConnectionManager;
import ch.boye.httpclientandroidlib.params.BasicHttpParams;
import ch.boye.httpclientandroidlib.params.HttpConnectionParams;
import ch.boye.httpclientandroidlib.params.HttpParams;
import ch.boye.httpclientandroidlib.params.HttpProtocolParams;
import ch.boye.httpclientandroidlib.protocol.HTTP;

import com.solcoo.common.App;
import com.solcoo.common.mobile.NetWork;
import com.solcoo.common.util.FileUtil;
import com.solcoo.merchant.ApplicationExt;
import com.solcoo.merchant.util.DialogUtil;
import com.solcoo.merchant.util.ViewUtil;

public class HttpDownloader {
	private static final String TAG = "HttpDownloader";
	public static final ThreadLocal<String> mThreadLocal = new ThreadLocal<String>(); // 在当前线程中保存触发该操作的activity
	private static final int TIMEOUT_CONNECTION = 5 * 1000; // 连接超时时间
	private static final int TIMEOUT_SOCKET = 20 * 1000; // 数据返回超时时间

	public static final String CONTENT_LENGTH = "content-length";// 头信息

	private static HttpClient httpClient = null;
	static {
		HttpParams params = new BasicHttpParams();
		HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
		HttpProtocolParams.setContentCharset(params,
				HTTP.DEFAULT_CONTENT_CHARSET);
		HttpConnectionParams.setConnectionTimeout(params, TIMEOUT_CONNECTION);
		HttpConnectionParams.setSoTimeout(params, TIMEOUT_SOCKET);
		SchemeRegistry registry = new SchemeRegistry();
		registry.register(new Scheme("http", 8080, PlainSocketFactory
				.getSocketFactory()));
		registry.register(new Scheme("https", 443, SSLSocketFactory
				.getSocketFactory()));

		PoolingClientConnectionManager ccm = new PoolingClientConnectionManager(
				registry);
		ccm.setDefaultMaxPerRoute(20);
		ccm.setMaxTotal(80);
		httpClient = new DefaultHttpClient(ccm, params);
	}

	public static HttpResult getConnectInputStream(String url) {
		Log.v(TAG, "load url:" + url);
		final String contextName = ApplicationExt.getInstance()
				.getCurrentContextName();
		HttpResult result = new HttpResult(HttpResult.API_RESULT_FAILED);
		if (!NetWork.isNetworkAvailable(App.CONTEXT)) {
			result.resultCode = HttpResult.API_RESULT_NETWORK_CLOSE;
			sendMessage(contextName, result.resultCode);
			return result;
		}

		try {
			HttpGet httpGet = new HttpGet(url);
			HttpResponse response = httpClient.execute(httpGet);
			// String length =
			// response.getFirstHeader(CONTENT_LENGTH).getValue();
			// TODO 检查长度

			result.resultCode = response.getStatusLine().getStatusCode();
			if (result.isSuccess()) {
				result.input = response.getEntity().getContent();
			} else {
				result.resultCode = HttpResult.API_RESULT_NETWORK_ERROR;
				sendMessage(contextName, result.resultCode);
			}
		} catch (ConnectTimeoutException e) {
			result.resultCode = HttpResult.API_RESULT_NETWORK_TIMEOUT;
			sendMessage(contextName, result.resultCode);
		} catch (Exception e) {
			Log.e(TAG, "getConnectInputStream error:", e);
			sendMessage(contextName, result.resultCode);
		}
		return result;
	}

	public static HttpResult getConnectData(String url) {
		HttpResult result = getConnectInputStream(url);
		if (!result.isSuccess()) {
			return result;
		}
		try {
			result.data = FileUtil.toByteArray(result.input);
		} catch (IOException e) {
			Log.e(TAG, "getConnectData error:", e);
		}
		return result;
	}

	public static HttpResult post(String url, Map<String, Object> params) {
		Log.v(TAG, "post url:" + url);
		final String contextName = ApplicationExt.getInstance()
				.getCurrentContextName();
		MultipartEntity entity = new MultipartEntity(
				HttpMultipartMode.BROWSER_COMPATIBLE);
		for (Entry<String, Object> param : params.entrySet()) {
			try {
				if (param.getValue() instanceof File) {
					entity.addPart(param.getKey(),
							new FileBody((File) param.getValue()));
				} else {
					entity.addPart(param.getKey(), new StringBody(param
							.getValue().toString(), Charset.forName("UTF-8")));
				}
			} catch (Exception e) {
				Log.e(TAG, "getConnectInputStream error:", e);
			}
		}
		HttpResult result = new HttpResult(HttpResult.API_RESULT_FAILED);
		HttpPost post = new HttpPost(url);
		post.setEntity(entity);
		try {
			HttpResponse response = httpClient.execute(post);
			result.resultCode = response.getStatusLine().getStatusCode();
			if (result.isSuccess()) {
				result.input = response.getEntity().getContent();
			} else {
				result.resultCode = HttpResult.API_RESULT_NETWORK_ERROR;
				sendMessage(contextName, result.resultCode);
			}
		} catch (ConnectTimeoutException e) {
			result.resultCode = HttpResult.API_RESULT_NETWORK_TIMEOUT;
			sendMessage(contextName, result.resultCode);
		} catch (Exception e) {
			Log.e(TAG, "getConnectInputStream error:", e);
			sendMessage(contextName, result.resultCode);
		}
		return result;
	}

	private static Handler netWorkHandler = new Handler(
			App.CONTEXT.getMainLooper()) {
		@Override
		public void handleMessage(Message msg) {
			String fromContext = msg.obj.toString();
			Context context = ApplicationExt.getInstance().getCurrentContext();
			switch (msg.what) {
			case HttpResult.API_RESULT_NETWORK_CLOSE:
				DialogUtil.createDialog(context, onWifiSettingClickListener,
						null, null, "亲,网络连接不可用,请设置", "网络设置");
				break;
			case HttpResult.API_RESULT_NETWORK_TIMEOUT:
				ViewUtil.showToastMsg(fromContext, "网络超时，请重试");
				break;
			default:
				ViewUtil.showToastMsg(fromContext, "网络异常，请重试");
				break;
			}
		}
	};

	private static OnClickListener onWifiSettingClickListener = new OnClickListener() {
		@Override
		public void onClick(DialogInterface dialog, int which) {
			dialog.dismiss();
			Intent intent = new Intent("android.settings.SETTINGS");
			ApplicationExt.getInstance().getCurrentContext()
					.startActivity(intent);
		}
	};

	private static void sendMessage(String contextName, int code) {
		Message msg = netWorkHandler.obtainMessage(code);
		msg.obj = contextName;
		netWorkHandler.sendMessage(msg);
	}

}
